import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.font_manager import FontProperties

# 设置全局字体配置
plt.rcParams['font.size'] = 10
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['text.usetex'] = False

# 创建支持中文的字体属性
chinese_font = FontProperties(fname=mpl.font_manager.findfont('SimHei'))

# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6), dpi=100)

# ================== 数据准备 ==================
# 裁剪阈值范围 (0.5-3.0)
thresholds = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.0])

# MNIST数据集上的准确率数据
mnist_accuracy = {
    '固定阈值': np.array([89.2, 92.5, 94.8, 95.5, 94.2, 92.0]),
    '自适应阈值(GP-AdaFL)': np.array([93.8, 95.2, 96.5, 96.8, 96.7, 96.5])
}

# CIFAR-10数据集上的准确率数据
cifar_accuracy = {
    '固定阈值': np.array([65.0, 70.2, 72.5, 73.8, 72.0, 70.5]),
    '自适应阈值(GP-AdaFL)': np.array([70.5, 73.8, 75.2, 75.5, 75.3, 74.8])
}

# ================== 绘制MNIST结果 ==================
# 绘制固定阈值曲线
ax1.plot(thresholds, mnist_accuracy['固定阈值'], 
         's-', color='#ff7f0e', linewidth=2, markersize=8,
         label='固定阈值')

# 绘制自适应阈值曲线
ax1.plot(thresholds, mnist_accuracy['自适应阈值(GP-AdaFL)'], 
         'o-', color='#1f77b4', linewidth=2, markersize=8,
         label='自适应阈值(GP-AdaFL)')

# 标注最优固定阈值点
fixed_peak_idx = np.argmax(mnist_accuracy['固定阈值'])
fixed_peak_thresh = thresholds[fixed_peak_idx]
fixed_peak_acc = mnist_accuracy['固定阈值'][fixed_peak_idx]
ax1.plot(fixed_peak_thresh, fixed_peak_acc, 's', markersize=10, 
         color='red', fillstyle='none', markeredgewidth=2)
ax1.annotate(f'固定阈值最优值\nC={fixed_peak_thresh}\n准确率={fixed_peak_acc}%', 
            xy=(fixed_peak_thresh, fixed_peak_acc), 
            xytext=(fixed_peak_thresh-0.8, fixed_peak_acc-3),
            arrowprops=dict(arrowstyle='->', color='red'),
            fontsize=10, fontproperties=chinese_font,
            bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="red", alpha=0.8))

# 标注自适应阈值优势
ax1.annotate('自适应阈值平均提升3.2%\n(尤其在低阈值区域)', 
            xy=(1.0, 95.5), 
            xytext=(1.5, 92),
            arrowprops=dict(arrowstyle='->', color='dimgray'),
            fontsize=10, fontproperties=chinese_font,
            bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="#1f77b4", alpha=0.8))

# 设置MNIST图形属性
ax1.set_xlim(0.4, 3.1)
ax1.set_ylim(85, 98)
ax1.set_title('(a) MNIST数据集', fontsize=12, fontproperties=chinese_font)
ax1.set_xlabel('裁剪阈值 (C)', fontsize=11, fontproperties=chinese_font)
ax1.set_ylabel('测试准确率 (%)', fontsize=11, fontproperties=chinese_font)
ax1.grid(True, linestyle='--', alpha=0.7)
ax1.legend(loc='lower right', prop=chinese_font)

# ================== 绘制CIFAR-10结果 ==================
# 绘制固定阈值曲线
ax2.plot(thresholds, cifar_accuracy['固定阈值'], 
         's-', color='#ff7f0e', linewidth=2, markersize=8,
         label='固定阈值')

# 绘制自适应阈值曲线
ax2.plot(thresholds, cifar_accuracy['自适应阈值(GP-AdaFL)'], 
         'o-', color='#1f77b4', linewidth=2, markersize=8,
         label='自适应阈值(GP-AdaFL)')

# 标注最优固定阈值点
fixed_peak_idx = np.argmax(cifar_accuracy['固定阈值'])
fixed_peak_thresh = thresholds[fixed_peak_idx]
fixed_peak_acc = cifar_accuracy['固定阈值'][fixed_peak_idx]
ax2.plot(fixed_peak_thresh, fixed_peak_acc, 's', markersize=10, 
         color='red', fillstyle='none', markeredgewidth=2)
ax2.annotate(f'固定阈值最优值\nC={fixed_peak_thresh}\n准确率={fixed_peak_acc}%', 
            xy=(fixed_peak_thresh, fixed_peak_acc), 
            xytext=(fixed_peak_thresh-0.8, fixed_peak_acc-5),
            arrowprops=dict(arrowstyle='->', color='red'),
            fontsize=10, fontproperties=chinese_font,
            bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="red", alpha=0.8))

# 标注自适应阈值优势
ax2.annotate('自适应阈值平均提升2.7%\n(尤其在Non-IID场景)', 
            xy=(1.5, 75.0), 
            xytext=(2.0, 70),
            arrowprops=dict(arrowstyle='->', color='dimgray'),
            fontsize=10, fontproperties=chinese_font,
            bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="#1f77b4", alpha=0.8))

# 设置CIFAR-10图形属性
ax2.set_xlim(0.4, 3.1)
ax2.set_ylim(60, 78)
ax2.set_title('(b) CIFAR-10数据集', fontsize=12, fontproperties=chinese_font)
ax2.set_xlabel('裁剪阈值 (C)', fontsize=11, fontproperties=chinese_font)
ax2.grid(True, linestyle='--', alpha=0.7)
ax2.legend(loc='lower right', prop=chinese_font)

# ================== 添加整体标题和结论 ==================
fig.suptitle('图9：裁剪阈值对模型准确率的影响分析', 
             fontsize=14, fontweight='bold', fontproperties=chinese_font)

# 添加关键结论标注
fig.text(0.5, 0.01, 
         '关键结论: 在Non-IID场景下(α=0.5)，自适应阈值机制使MNIST准确率平均提升3.2%，CIFAR-10提升2.7%', 
         ha="center", fontsize=12, fontproperties=chinese_font, 
         bbox=dict(boxstyle="round,pad=0.3", fc="#f0f0f0", ec="black", alpha=0.8))

# 添加技术标注
fig.text(0.5, -0.05, 
         "实验设置: 隐私预算ε=5 | 客户端数量:20 | MNIST模型:LeNet-5 | CIFAR-10模型:ResNet-18", 
         ha="center", fontsize=10, style='italic', fontproperties=chinese_font)

# 调整布局并保存
plt.tight_layout(rect=[0, 0.05, 1, 0.95])
plt.savefig('clipping_threshold_sensitivity.png', bbox_inches='tight', dpi=300)
plt.show()
